#include "skybox.h"

CSkyBox::CSkyBox()
    : m_szTexturePath("textures/skybox/grassland_skybox.png")
{
    //LPD3DXMESH *pMesh(new LPD3DXMESH);
    LPD3DXMESH mesh;
    D3DXCreateBox(CDeviceManager::getInstance()->getDevice(), 2.0f, 2.0f, 2.0f,
                  &mesh, nullptr);
    CMesh *pCMesh(CMeshContainer::getInstance()->addMesh("box"));
    pCMesh->loadMesh(mesh);
    //delete pMesh;
    CDisplayable *pDisplayable(
        CDisplayableContainer::getInstance()->createDisplayable(pCMesh));
    //CDisplayableContainer::getInstance()->insertDisplayable(pDisplayable);
    pDisplayable->setTranslate(0.0f, 0.0f, 0.0f);

    TVertex arrMesh[24] =
    {
        // Front quad, NOTE: All quads face inward
        
        // Front
        {-10.0f, -10.0f,  10.0f,  0.25f, 2/3.0f },
        {-10.0f,  10.0f,  10.0f,  0.25f, 1/3.0f },
        { 10.0f, -10.0f,  10.0f,  0.50f, 2/3.0f },
        { 10.0f,  10.0f,  10.0f,  0.50f, 1/3.0f },
        
        // Back quad
        { 10.0f, -10.0f, -10.0f,  0.75f, 2/3.0f },
        { 10.0f,  10.0f, -10.0f,  0.75f, 1/3.0f },
        {-10.0f, -10.0f, -10.0f,  1.0f, 2/3.0f },
        {-10.0f,  10.0f, -10.0f,  1.0f, 1/3.0f },
        
        // Left quad
        {-10.0f, -10.0f, -10.0f,  0.0f, 2/3.0f },
        {-10.0f,  10.0f, -10.0f,  0.0f, 1/3.0f },
        {-10.0f, -10.0f,  10.0f,  0.25f, 2/3.0f },
        {-10.0f,  10.0f,  10.0f,  0.25f, 1/3.0f },
        
        // Right quad
        { 10.0f, -10.0f,  10.0f,  0.5f, 2/3.0f },
        { 10.0f,  10.0f,  10.0f,  0.5f, 1/3.0f },
        { 10.0f, -10.0f, -10.0f,  0.75f, 2/3.0f },
        { 10.0f,  10.0f, -10.0f,  0.75f, 1/3.0f },

        // Top quad
        {-10.0f,  10.0f,  10.0f,  0.25f, 1/3.0f },
        {-10.0f,  10.0f, -10.0f,  0.25f, 0.0f },
        { 10.0f,  10.0f,  10.0f,  0.5f, 1/3.0f },
        { 10.0f,  10.0f, -10.0f,  0.5f, 0.0f },
        
        // Bottom quad
        {-10.0f, -10.0f, -10.0f,  0.25f, 1.0f },
        {-10.0f, -10.0f,  10.0f,  0.25f, 2/3.0f },
        { 10.0f, -10.0f, -10.0f,  0.5f, 1.0f },
        { 10.0f, -10.0f,  10.0f,  0.5f, 2/3.0f}
    };

    memcpy(m_arrMesh, arrMesh, sizeof(TVertex) * 24);

    CDeviceManager::getInstance()->getDevice()->CreateVertexBuffer(
        sizeof(TVertex) * 24,   // size of vertex buffer in bytes
        0,                      // Usage - 0 is hardware vertex processing
        D3DFVF_XYZ|D3DFVF_TEX1, // The vertex format
        D3DPOOL_MANAGED,        // Memory pool is managed by the device
        &m_pBuffer,             // the vertex buffer !NULL is successful
        nullptr);               // Reserved

    void *pVertices(nullptr);

    m_pBuffer->Lock(0, sizeof(TVertex) * 24, (void**)&pVertices, 0);
    memcpy(pVertices, m_arrMesh, sizeof(TVertex) * 24);
    m_pBuffer->Unlock();

    changeSkybox(m_szTexturePath);

}

void CSkyBox::changeSkybox(string szPath)
{
    CTextureContainer *pTextures(CTextureContainer::getInstance());
    CTexture *pTexture(pTextures->addTexture(szPath, szPath,
        CDeviceManager::getInstance()->getDevice()));

    pTexture->setPermanent(true);
    m_szTexturePath = szPath;
}

CSkyBox::~CSkyBox()
{
    m_pBuffer->Release();
}

CSkyBox *CSkyBox::getInstance()
{
    static CSkyBox s_instance;
    return &s_instance;
}

void CSkyBox::render()
{
    CTextureContainer *pTextures(CTextureContainer::getInstance());
    LPDIRECT3DDEVICE9 pDevice(CDeviceManager::getInstance()->getDevice());

    pDevice->SetFVF(D3DFVF_XYZ|D3DFVF_TEX1);
    pDevice->SetStreamSource(0, m_pBuffer, 0, sizeof(TVertex));

    pTextures->getTexture(m_szTexturePath)->applyTexture(0, pDevice);

    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 8, 2);
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 12, 2);
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 16, 2);
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 20, 2);
}